{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    " # How to use the BRON arangodb\n",
    " \n",
    " You can view the public version of BRON with the arangodb web interface at [http:bron.alfa.csail.mit.edu:8529] with `username` `guest` and `password` `guest`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "# Change working directory\n",
    "import os\n",
    "cwd = os.path.split(os.getcwd())\n",
    "if cwd[-1] == 'graph_db':\n",
    "    os.chdir('..')\n",
    "\n",
    "assert os.path.split(os.getcwd())[-1] == 'BRON'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "import arango\n",
    "from graph_db.bron_example_for_detecting_abuse_of_authentication_mechanism_report import REPORT_URL as THREAT_REPORT_URL, MDR_URL, FIRE_EYE_URL\n",
    "from graph_db.bron_example_for_detecting_abuse_of_authentication_mechanism_report import main as download_report_extract_ttps_query_bron\n",
    "\n",
    "BRON_SERVER_IP = 'bron.alfa.csail.mit.edu'\n",
    "BRON_USERNAME = 'guest'\n",
    "BRON_PASSWORD = 'guest'\n",
    "DB = 'BRON'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## Example connect to BRON arangodb and perform AQL query"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'_key': 'tactic_00009', '_id': 'tactic/tactic_00009', '_rev': '_bmbn28S---', 'original_id': 'TA0006', 'datatype': 'tactic', 'name': 'credential-access', 'metadata': {}}\n",
      "CPU times: user 9.15 ms, sys: 3.38 ms, total: 12.5 ms\n",
      "Wall time: 125 ms\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "query = \"\"\"\n",
    "FOR c IN tactic\n",
    "    FILTER c.original_id == \"TA0006\"\n",
    "    RETURN c\n",
    "\"\"\"\n",
    "client = arango.ArangoClient(hosts=f\"http://{BRON_SERVER_IP}:8529\")\n",
    "db = client.db(DB, username=BRON_USERNAME, password=BRON_PASSWORD, auth_method=\"basic\")\n",
    "assert db.aql.validate(query)\n",
    "cursor = db.aql.execute(query)\n",
    "for c in cursor:\n",
    "    print(c)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "FOR c IN capec\n",
      "    FILTER c.original_id == \"117\"\n",
      "    FOR v IN 1..1 ANY c TechniqueCapec\n",
      "        RETURN v\n",
      "\n",
      "1 result for CAPEC 117 in TechniqueCapec: {'T1020.001'}\n",
      "\n",
      "FOR c IN capec\n",
      "    FILTER c.original_id == \"117\"\n",
      "    FOR v IN 1..1 ANY c CapecCwe\n",
      "        RETURN v\n",
      "\n",
      "1 result for CAPEC 117 in CapecCwe: {'319'}\n",
      "CPU times: user 11.7 ms, sys: 2.93 ms, total: 14.6 ms\n",
      "Wall time: 172 ms\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "query_template = \"\"\"\n",
    "FOR c IN capec\n",
    "    FILTER c.original_id == \"{}\"\n",
    "    FOR v IN 1..1 ANY c {}\n",
    "        RETURN v\n",
    "\"\"\"\n",
    "capec = \"117\"\n",
    "edge_collections = (\"TechniqueCapec\", \"CapecCwe\")\n",
    "for edge_collection in edge_collections:\n",
    "    query = query_template.format(capec, edge_collection)\n",
    "    assert db.aql.validate(query)\n",
    "    print(query)\n",
    "    cursor = db.aql.execute(query)\n",
    "    results = {_['original_id'] for _ in cursor}\n",
    "    print(f'{len(results)} result for CAPEC {capec} in {edge_collection}: {results}')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## Example report download, threat data extraction and BRON query\n",
    "\n",
    "- Given a URL (in this example https://media.defense.gov/2020/Dec/17/2002554125/-1/-1/0/AUTHENTICATION_MECHANISMS_CSA_U_OO_198854_20.PDF )\n",
    "- Parse the document at the URL (HTML or PDF) and use regexp to identify Tactics, Techniques and CVEs\n",
    "- Query the collections in BRON with the extracted information \n",
    "- Prints\n",
    " - the queried records for each collection and the number of edges from each record\n",
    " - the number of edges from traversals of BRON given the records"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Query results records: {\n",
      " \"tactic\": {\n",
      "  \"TA0006\": {\n",
      "   \"technique\": 49\n",
      "  }\n",
      " },\n",
      " \"technique\": {\n",
      "  \"T1552.004\": {\n",
      "   \"tactic\": 1\n",
      "  },\n",
      "  \"T1114.002\": {\n",
      "   \"tactic\": 1\n",
      "  },\n",
      "  \"T1552\": {\n",
      "   \"tactic\": 1\n",
      "  },\n",
      "  \"T1114\": {\n",
      "   \"tactic\": 1\n",
      "  },\n",
      "  \"T1199\": {\n",
      "   \"tactic\": 1\n",
      "  }\n",
      " },\n",
      " \"cve\": {}\n",
      "}\n",
      "Query results number of traversals: {\n",
      " \"tactic\": 6,\n",
      " \"technique\": 9,\n",
      " \"cve\": 3\n",
      "}\n",
      "CPU times: user 9.84 s, sys: 1.04 s, total: 10.9 s\n",
      "Wall time: 52.3 s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "_ = download_report_extract_ttps_query_bron(BRON_SERVER_IP, BRON_PASSWORD, BRON_USERNAME, url=THREAT_REPORT_URL)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example using file with a network description\n",
    "\n",
    "As above but the results are filtered based on CPE format matches with the affected product configurations listed in a network description file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Query results records: {\n",
      " \"tactic\": {\n",
      "  \"TA0006\": {\n",
      "   \"technique\": 49\n",
      "  }\n",
      " },\n",
      " \"technique\": {\n",
      "  \"T1552.004\": {\n",
      "   \"tactic\": 1\n",
      "  },\n",
      "  \"T1114.002\": {\n",
      "   \"tactic\": 1\n",
      "  },\n",
      "  \"T1552\": {\n",
      "   \"tactic\": 1\n",
      "  },\n",
      "  \"T1114\": {\n",
      "   \"tactic\": 1\n",
      "  },\n",
      "  \"T1199\": {\n",
      "   \"tactic\": 1\n",
      "  }\n",
      " },\n",
      " \"cve\": {}\n",
      "}\n",
      "Query results number of traversals: {\n",
      " \"tactic\": 6,\n",
      " \"technique\": 9,\n",
      " \"cve\": 3\n",
      "}\n",
      "Number of configurations in CPE format in network 18\n",
      "Network matches: {\n",
      " \"tactic\": [\n",
      "  \"TA0006\"\n",
      " ]\n",
      "}\n",
      "CPU times: user 9.93 s, sys: 1.06 s, total: 11 s\n",
      "Wall time: 51.6 s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "network_description_file = 'graph_db/example_data/network_file_bron.json'\n",
    "_ = download_report_extract_ttps_query_bron(BRON_SERVER_IP, BRON_PASSWORD, BRON_USERNAME, url=THREAT_REPORT_URL,\n",
    "                                            network_description_file=network_description_file)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
